﻿/*========================== 
 * @author 郑金泉
 * @desc SQL 逻辑运算 条件类
 * ========================= */
using System;
using System.Collections.Generic;
using System.Text;

using Obsidian.Edm;

namespace Obsidian.Data.Sql
{
    public class CompareCondition : SqlCondition, ISqlCondition
    {

        private ModelField _modelField;
        private string _compareOperator = null;
        private object _value = null;
        private ModelField _targetField = null;

        public CompareCondition(ModelField field, string compareOperator, object value)
        {
            this.Init(Sql.LogicalOperator.AND, field, compareOperator, value, null);
        }

        public CompareCondition(LogicalOperator logicalOperator, ModelField field, string compareOperator, object value)
        {
            this.Init(logicalOperator, field, compareOperator, value, null);
        }

        public CompareCondition(ModelField field, string compareOperator, ModelField targetField)
        {
            this.Init(Sql.LogicalOperator.AND, field, compareOperator, null, targetField);
        }

        public CompareCondition(LogicalOperator logicalOperator, ModelField field, string compareOperator, ModelField targetField)
        {
            this.Init(logicalOperator, field, compareOperator, null, targetField);
        }

        private void Init(LogicalOperator logicalOperator, ModelField field, string compareOperator, object value, ModelField targetField)
        {
            if (!this.CheckCompareOperator(compareOperator))
                throw new Exception("比较操作符\"" + compareOperator + "\"错误!");
            this.LogicalOperator = logicalOperator;
            this._modelField = field;
            this._compareOperator = compareOperator;
            this._value = value;
            this._targetField = targetField;
        }

        public string BuildSqlText()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(this._modelField.GetDbField().TablePrefixName);
            if (Convert.IsDBNull(this._value))
            {
                if (this._compareOperator == "=")
                    sb.Append(" IS NULL ");
                else
                    sb.Append(" IS NOT NULL ");
            }
            else
            {
                sb.Append(" ").Append(this._compareOperator).Append(" ");
                if (this._value != null)
                {
                    if (this._value.GetType() == typeof(string))
                    {
                        DataBaseType dbType = this._modelField.Model.GetDataBase().Type;
                        string val = DbHandler.Escape(dbType, this._value.ToString());
                        sb.Append("'").Append(val).Append("'");
                    }
                    else if (this._value.GetType() == typeof(DateTime))
                        sb.Append("'").Append(((DateTime)this._value).ToString("yyyy-MM-dd hh:mm:ss")).Append("'");
                    else if (this._value.GetType() == typeof(Boolean))
                        sb.Append(this._value.Equals(true) ? 1 : 0);
                    else
                        sb.Append(this._value.ToString());
                }
                else
                {
                    sb.Append(this._targetField.GetDbField().TablePrefixName);
                }
            }
            return sb.ToString();
        }

        private bool CheckCompareOperator(string compareOperator)
        {
            return compareOperator.Equals("=") ||
                compareOperator.Equals(">") ||
                compareOperator.Equals("<") ||
                compareOperator.Equals("<>") ||
                compareOperator.Equals(">=") ||
                compareOperator.Equals("<=");
        }

    }
}
